Author: Jorge Maldonado Ventura
Category: Desarrollo web
Date: 2017-06-23 04:05
Image: <img src="/wp-content/uploads/2017/06/tree-html-css.png" alt="Salida del programa tree en HTML y CSS">
Lang: es
Slug: estructura-de-árbol-con-css-html
Tags: CSS, HTML, páginas web
Title: Estructura de árbol con CSS y HTML

A veces viene bien poder representar datos en una estructura de árbol
como la que produce el programa tree. El programa tree produce una
salida de un árbol de directorios como esta:

<pre><samp>
✔ /var/www/html/Repos/Freak-Spot/freak-theme [master|✔] $ tree
.
├── static
│   ├── css
│   │   └── style.css
│   ├── genericons
│   │   ├── COPYING.txt
│   │   ├── genericons.css
│   │   ├── Genericons.eot
│   │   ├── Genericons.svg
│   │   ├── Genericons.ttf
│   │   ├── Genericons.woff
│   │   ├── LICENSE.txt
│   │   └── README.md
│   ├── images
│   │   ├── creativecommons_public-domain_80x15.png
│   │   ├── gnu-head-mini.png
│   │   └── questioncopyright-favicon.png
│   └── js
│       ├── functions.js
│       └── jquery-3.1.1.js
└── templates
    ├── archives.html
    ├── article.html
    ├── article_info.html
    ├── author.html
    ├── authors.html
    ├── base.html
    ├── category.html
    ├── index.html
    ├── page.html
    ├── pagination.html
    ├── period_archives.html
    ├── tag.html
    ├── taglist.html
    └── tags.html

6 directories, 28 files
</samp></pre>

Para representar la instrucción tal como aparece en una terminal he
utilizado las etiquetas <abbr title="HyperText Markup
Language">HTML</abbr> `<samp>` y `<pre>` (`<pre><samp>salida de
tree</samp></pre>`). ¿Pero que pasa si quiero incluir un enlace o
utilizar otros elementos de <abbr title="HyperText Markup
Language">HTML</abbr>, o <abbr title="Cascading Style Sheets">CSS</abbr>?
Entonces tendremos que usar CSS para mostrar la apariencia de ramas.

<!-- more -->

Vamos a usar la salida anterior como ejemplo. Esta se puede expresar
así en  <abbr title="HyperText Markup
Language">HTML</abbr>:

    :::html
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="UTF-8">
        <title>Lista en árbol</title>
      </head>
      <body>
        <div class="contenedor-arbol">
          <ul>
            <li>static
              <ul>
                <li>css
                  <ul>
                    <li>style.css</li>
                  </ul>
                </li>
                 <li>genericons
                   <ul>
                     <li>COPYING.txt</li>
                     <li>genericons.css</li>
                     <li>Genericons.eot</li>
                     <li>Genericons.svg</li>
                     <li>Genericons.ttf</li>
                     <li>Genericons.woff</li>
                     <li>LICENSE.txt</li>
                     <li>README.md</li>
                   </ul>
                 </li>
                <li>images
                  <ul>
                    <li>creativecommons_public-domain_80x15.png</li>
                    <li>gnu-head-mini.png</li>
                    <li>questioncopyright-favicon.png</li>
                  </ul>
                </li>
                <li>js
                  <ul>
                    <li>functions.js</li>
                    <li>jquery-3.1.1.js</li>
                  </ul>
                  </li>
              </ul>
            </li>
            <li>templates
              <ul>
                <li>archives.html</li>
                <li>article.html</li>
                <li>article_info.html</li>
                <li>author.html</li>
                <li>authors.html</li>
                <li>base.html</li>
                <li>category.html</li>
                <li>index.html</li>
                <li>page.html</li>
                <li>pagination.html</li>
                <li>period_archives.html</li>
                <li>tag.html</li>
                <li>taglist.html</li>
                <li>tags.html</li>
              </ul>
            </li>
          </ul>
        </div>
      </body>
    </html>

Primero debemos establecer las reglas para que la lista y su contenedor
no interfieran con el dibujo que haremos posteriormente utilizando la
regla `border` de <abbr title="Cascading Style Sheets">CSS</abbr>.

    :::css
    .contenedor-arbol, .contenedor-arbol ul, .contenedor-arbol li {
        position: relative;
    }

    .contenedor-arbol ul {
        list-style: none;
    }

A continuación cambiamos la posición de los pseudoelementos para tener
espacio para las líneas del árbol.

    :::css
    .contenedor-arbol li::before, .contenedor-arbol li::after {
        content: "";
        position: absolute;
        left: -12px;
    }

Posteriormente, utilizando pseudoelementos dibujamos las líneas
horizontales (`::before`) y las verticales (`::after`).

    :::css
    .arbol li::before {
        border-top: 1px solid green;
        top: 9px;
        width: 8px;
        height: 0;
    }

    .arbol li::after {
        border-left: 1px solid brown;
        height: 100%;
        width: 0px;
        top: 2px;
    }

El último retoque es hacer que la rama no se extienda de más en el
último elemento.


    :::css
    .clt ul > li:last-child::after {
        height: 8px;
    }

El resultado es el siguiente:

<iframe allowfullscreen src="/wp-content/uploads/2017/06/estructura-de-árbol-con-css-html.html" style="width: 100%"></iframe>

Abajo dejo el código completo. Obviamente, se pueden hacer
modificaciones y cambiar muchas medidas para lograr una apariencia y una
funcionalidad más personalizada.


    :::html
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="UTF-8">
        <title>Lista en árbol</title>
        <style>
          .contenedor-arbol, .contenedor-arbol ul, .contenedor-arbol li {
              position: relative;
          }

          .contenedor-arbol ul {
              list-style: none;
          }

          .contenedor-arbol li::before, .contenedor-arbol li::after {
              content: "";
              position: absolute;
              left: -12px;
          }

          .contenedor-arbol li::before {
              border-top: 2px solid green;
              top: 9px;
              width: 8px;
              height: 0;
          }

          .contenedor-arbol li::after {
              border-left: 2px solid brown;
              height: 100%;
              width: 0px;
              top: 2px;
          }

          .contenedor-arbol ul > li:last-child::after {
              height: 8px;
          }
        </style>
      </head>
      <body>
        <div class="contenedor-arbol">
          <ul>
            <li>static
              <ul>
                <li>css
                  <ul>
                    <li>style.css</li>
                  </ul>
                </li>
                 <li>genericons
                   <ul>
                     <li>COPYING.txt</li>
                     <li>genericons.css</li>
                     <li>Genericons.eot</li>
                     <li>Genericons.svg</li>
                     <li>Genericons.ttf</li>
                     <li>Genericons.woff</li>
                     <li>LICENSE.txt</li>
                     <li>README.md</li>
                   </ul>
                 </li>
                <li>images
                  <ul>
                    <li>creativecommons_public-domain_80x15.png</li>
                    <li>gnu-head-mini.png</li>
                    <li>questioncopyright-favicon.png</li>
                  </ul>
                </li>
                <li>js
                  <ul>
                    <li>functions.js</li>
                    <li>jquery-3.1.1.js</li>
                  </ul>
                  </li>
              </ul>
            </li>
            <li>templates
              <ul>
                <li>archives.html</li>
                <li>article.html</li>
                <li>article_info.html</li>
                <li>author.html</li>
                <li>authors.html</li>
                <li>base.html</li>
                <li>category.html</li>
                <li>index.html</li>
                <li>page.html</li>
                <li>pagination.html</li>
                <li>period_archives.html</li>
                <li>tag.html</li>
                <li>taglist.html</li>
                <li>tags.html</li>
              </ul>
            </li>
          </ul>
        </div>
      </body>
    </html>
